//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Base/Include/Common.h"

namespace Engine
{
namespace Base
{


	//
	// Const Reference
	//

	template <typename T>
	struct ConstReference
	{
	// types
	public:
		typedef ConstReference<T>	Self;


	// variables
	private:
		Ptr< T >	_value;


	// methods
	private:
		ConstReference () {}
		void operator = (const Self &) {}

	public:
		explicit
		ConstReference (T &value) : _value(&value) {}

		ConstReference (const Self &other) : _value(other._value) {}

		explicit
		ConstReference (void *ptr) : _value(null) { ASSERT( ptr == null ); }

		T *			operator -> ()			{ return _value; }
		T *			operator -> ()	const	{ return (T *)_value; }

		T *			raw_ptr ()				{ return _value; }
		T const *	raw_ptr ()		const	{ return _value; }

		void Override (const Self &ref)
		{
			_value = ref._value;
		}
	};

}	// Base



#	define ENGINE_SUBSYSTEM( _type, _name ) \
		private: \
			friend class _type; \
			Ptr< _type >	__##_name; \
			\
			void Set##_name (_type *p) \
			{ \
				ASSERT( p == null or __##_name.IsNull() ); \
				__##_name = p; \
			} \
			\
			void Override##_name (_type *p) \
			{ \
				__##_name = p; \
			} \
			\
		public: \
			Ptr< _type >	Get##_name ()	{ return __##_name; }


	
	//
	// All Engine subsystems
	//

	struct EngineSubSystems
	{
		ENGINE_SUBSYSTEM( Base::IParallelThread,		CurrentThread	)
		ENGINE_SUBSYSTEM( Base::ResourceManager,		ResourceManager	)
		ENGINE_SUBSYSTEM( Base::EventSystem,			EventSystem		)
		ENGINE_SUBSYSTEM( Base::Input,					Input			)
		ENGINE_SUBSYSTEM( Base::ParallelThreadManager,	ThreadManager	)
		ENGINE_SUBSYSTEM( Platforms::IApplication,		Application		)
		ENGINE_SUBSYSTEM( Platforms::IFileSystem,		FileSystem		)
		ENGINE_SUBSYSTEM( Graphics::GraphicsEngine,		GraphicsEngine	)
		ENGINE_SUBSYSTEM( Graphics::StateManager,		GLStateManager	)
		ENGINE_SUBSYSTEM( Audio::AudioEngine,			AudioEngine		)
		ENGINE_SUBSYSTEM( UI::UserInterface,			UserInterface	)
		ENGINE_SUBSYSTEM( Scene2D::SceneManager,		SceneManager2D	)
		ENGINE_SUBSYSTEM( Scene3D::SceneManager,		SceneManager3D	)
		ENGINE_SUBSYSTEM( Physics::PhysicsEngine,		PhysicsEngine	)

		EngineSubSystems ()
		{}

		EngineSubSystems (const EngineSubSystems &other)
		{
			MemCopy( this, &other, sizeof(*this) );
		}

		EngineSubSystems & operator = (const EngineSubSystems &right)
		{
			MemCopy( this, &right, sizeof(*this) );
			return *this;
		}
	};

	typedef Base::ConstReference< EngineSubSystems >		EngineSubSystemsRef;




}	// Engine